package com.gdzn.netty.service.impl;

import cn.hutool.json.JSONUtil;
import com.gdzn.common.core.utils.JsonUtil;
import com.gdzn.netty.domain.DeviceCallParam;
import com.gdzn.netty.redis.queue.MessageSender;
import com.gdzn.netty.service.IDeviceRedisService;
import com.gdzn.netty.service.IDeviceService;
import com.gdzn.netty.service.IRemoteCallService;
import com.gdzn.common.core.utils.DateUtils;

import com.gdzn.netty.service.*;

import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @description: 发送消息给前端
 * @author:
 * @created: 2024-04-18
 * @version: V1.0
 */
@Slf4j
@Component
public class RemoteCallServiceImpl implements IRemoteCallService {

    @Autowired
    private IDeviceRedisService deviceRedisService;

    @Autowired
    private IDeviceService deviceService;


    @Override
    public boolean callDevice(DeviceCallParam deviceCallParam) {
        log.info("******callDevice**推送命令操作设备,deviceCallParam:{}", deviceCallParam);
        String devId = deviceCallParam.getDevId();
        ChannelHandlerContext ctx = deviceRedisService.getChannelByDevId(devId);
        if (null != ctx) {
            deviceCallParam.setTxnNo(System.currentTimeMillis());
            sendByChannel(JSONUtil.toJsonStr(deviceCallParam), ctx);
        }else{
            log.info("******callDevice**获取不到channel***");
            return false;
        }
        return true;
    }

    @Autowired
    private MessageSender messageSender;

    @Override
    public boolean callDeviceByRedis(DeviceCallParam deviceCallParam) {
        log.info("******redis pub callDevice**推送命令操作设备,deviceCallParam:{}", deviceCallParam);
        messageSender.sendMessage(JSONUtil.toJsonStr(deviceCallParam));
        return true;
    }

    @Override
    public boolean callDeviceForMapByRedis(Map<String, Object> map) {
        log.info("******redis pub callDevice**推送命令操作设备,deviceCallParam:{}", map);
        messageSender.sendMessage(map);
        return true;
    }

    @Override
    public boolean callDeviceForMap(Map<String, Object> map) {
        log.info("******callDeviceForMap**推送命令操作设备,map:{}", map);
        String devId = (String)map.get("devId");
        map.put("txnNo",System.currentTimeMillis());
        ChannelHandlerContext ctx = deviceRedisService.getChannelByDevId(devId);
        if (null != ctx) {
            sendByChannel(JSONUtil.toJsonStr(map), ctx);
        }else{
            log.info("******callDeviceForMap**获取不到channel***");
            return false;
        }
        return true;
    }



    /**
     * 通过管道->推送消息到客户端
     * @param resp
     * @param ctx
     */
    private void sendByChannel(String resp, ChannelHandlerContext ctx){
        log.info("***sendByChannel***时间：{}, 开始发送给客户端：{}", DateUtils.getTime(), JsonUtil.toJSON(resp));
        String channelId = ctx.channel().id().asLongText();
        //String resp = JSONUtil.toJsonStr(deviceCallParam);
        ctx.channel().writeAndFlush(resp);
        log.info("***sendByChannel***返回给管道channelId:{},客户端", channelId);
    }
}
